package cn.tedu.spotms.server.service.impl;

import cn.tedu.spotms.server.ex.ServiceException;
import cn.tedu.spotms.server.mapper.PermissionMapper;
import cn.tedu.spotms.server.mapper.RoleMapper;
import cn.tedu.spotms.server.pojo.dto.RoleAddNewDTO;
import cn.tedu.spotms.server.pojo.dto.RoleMatchPermissionsDTO;
import cn.tedu.spotms.server.pojo.entity.Role;
import cn.tedu.spotms.server.pojo.vo.PermissionStandardVO;
import cn.tedu.spotms.server.pojo.vo.RoleListItemVO;
import cn.tedu.spotms.server.service.IRoleService;
import cn.tedu.spotms.server.web.State;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

@Service
@Slf4j
public class RoleServiceImpl implements IRoleService {

    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public void addNew(RoleAddNewDTO roleAddNewDTO) {
        // 从参数获取角色名字
        String name = roleAddNewDTO.getName();
        log.debug("想要添加的角色名字name={}",name);
        // 根据名字查询数据库，并判断结果是否不为null，如果是，抛出异常
        RoleListItemVO result = roleMapper.getByName(name);
        log.debug("根据名字({})查询结果role:{}",name,result);
        if (result != null) {
            log.debug("角色已存在，即将抛出异常!");
            throw new ServiceException(State.ERR_ROLE_NAME_DUPLICATE,"添加角色失败，角色("+name+")已存在!");
        }

        // 创建Role对象，从参数复制信息到Role对象
        Role role = new Role();
        BeanUtils.copyProperties(roleAddNewDTO,role);
        // 补全gmtCreate和gmtModified属性值
        LocalDateTime now = LocalDateTime.now();
        role.setGmtCreate(now);
        role.setGmtModified(now);

        // 调用mapper方法插入数据，并判断返回值，不为1则抛出异常
        log.debug("即将插入角色信息role={}",role);
        int rows = roleMapper.insert(role);
        if (rows != 1) {
            log.debug("添加角色失败，即将抛出异常!");
            throw new ServiceException(State.ERR_INSERT,"添加角色失败，服务器忙，请稍后再试!");
        }
        log.debug("添加角色成功!");
    }

    @Override
    public void matchPermissions(RoleMatchPermissionsDTO roleMatchPermissionsDTO) {
        // 获取角色id
        Long roleId = roleMatchPermissionsDTO.getRoleId();
        log.debug("想要配置权限的角色id={}",roleId);
        // 通过角色id查询数据库，判断结果是否为null，若为null，抛出异常
        RoleListItemVO role = roleMapper.getById(roleId);
        if (role == null) {
            log.debug("角色id({})不存在，即将抛出异常",roleId);
            throw new ServiceException(State.ERR_ROLE_NOT_FOUND,"配置权限失败，角色("+roleId+")不存在!");
        }

        // 获取权限集合
        List<Long> permissions = roleMatchPermissionsDTO.getPermissions();
        log.debug("想要配置的权限id为:{}",permissions);
        // 如果权限集合为null或空集，抛出异常
        if (permissions == null || permissions.isEmpty()) {
            log.debug("权限为空，即将抛出异常");
            throw new ServiceException(State.ERR_PERMISSION_EMPTY,"配置权限失败，权限不能为空!");
        }

        // 遍历集合，通过每个权限id查询数据库，并判断结果是否为null，若为null，抛出异常
        for (Long permissionId : permissions) {
            PermissionStandardVO permission = permissionMapper.getById(permissionId);
            if (permission == null) {
                log.debug("权限id({})不存在，即将抛出异常",permissionId);
                throw new ServiceException(State.ERR_PERMISSION_NOT_FOUND,"配置权限失败，权限("+permissionId+")不存在!");
            }
        }

        // 通过角色id查询出ms_role_permission表中原有数据
        List<Long> rawPermissions = roleMapper.getPermissionsById(roleId);
        if (!rawPermissions.isEmpty()) {
            // 根据角色id删除ms_role_permission表中原有数据
            int rows = roleMapper.deletePermissionsById(roleId);
            if (rows != rawPermissions.size()) {
                log.debug("删除原有权限数据操作失败，即将抛出异常!");
                throw new ServiceException(State.ERR_UPDATE,"配置权限失败，服务器忙，请稍后再试!");
            }
        }

        // 向ms_role_permission表中插入新数据，并判断影响行数
        LocalDateTime now  = LocalDateTime.now();
        int rows = roleMapper.insertPermissionsById(roleId, permissions, now);
        if (rows != permissions.size()) {
            log.debug("插入权限数据操作失败，即将抛出异常!");
            throw new ServiceException(State.ERR_UPDATE,"配置权限失败，服务器忙，请稍后再试!");
        }

        // 修改角色的更新时间
        updateGmtModifiedById(roleId);
        log.debug("配置权限完成!");
    }

    @Override
    public List<RoleListItemVO> list() {
        return roleMapper.list();
    }


    private void updateGmtModifiedById(Long id) {
        // 修改gmt_modified字段值，更新修改时间
        log.debug("开始修改更新时间");
        LocalDateTime gmtModified = LocalDateTime.now();
        int rows = roleMapper.updateGmtModifiedById(id, gmtModified);
        if (rows != 1) {
            log.debug("修改更新时间操作失败，即将抛出异常!");
            throw new ServiceException(State.ERR_UPDATE,"更新数据失败，系统忙，请稍后再试!");
        }
        log.debug("修改更新时间完成");
    }
}
